#pragma once
#include <vector>
#include <set>
#include <algorithm>

#include "VCBase.h"
#include "VCRefPtr.h"

namespace LBPROJ
{
    template<typename IObjectType>
    class CIteratorTool : public Iterator<IObjectType*>
    {
        IMPLEMENT_REFCOUNTING(CIteratorTool)
    public:
        template<class Container>
        CIteratorTool(const Container& container, bool reversed = false)
        {
            m_childRCJ.reserve(container.size());
            if(reversed)
                m_childRCJ.insert(m_childRCJ.end(), container.rbegin(), container.rend());
            else
                m_childRCJ.insert(m_childRCJ.end(), container.begin(), container.end());
        }

    public:
        virtual void First()
        {
            m_curPos = m_childRCJ.begin();
        }
        virtual void Next()
        {
            ++m_curPos;
        }
        virtual bool IsDone() const
        {
            return m_curPos == m_childRCJ.end();
        }
        virtual IObjectType* GetCurrentItem() const
        {
            return *m_curPos;
        }
        virtual size_t GetCount() const
        {
            return m_childRCJ.size();
        }
        virtual IObjectType* GetChild(int index) const
        {
            if (index >= 0 && index < m_childRCJ.size())
            {
                return m_childRCJ[index];
            }
            return nullptr;
        }
        virtual int IndexOf(IObjectType* obj) const
        {
            for (int i = 0; i < m_childRCJ.size(); ++i)
            {
                if (m_childRCJ[i] == obj)
                {
                    return i;
                }
            }
            return 0;
        }
    private:
        typename std::vector<CRefPtr<IObjectType>>::iterator m_curPos;
        typename std::vector<CRefPtr<IObjectType>> m_childRCJ;
    };
}